package cn.wolfcode.service.impl;

import cn.wolfcode.config.DeepSeekProperties;
import cn.wolfcode.domain.Strategy;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.*;

@Service
public class DeepSeekService {

    @Autowired
    private DeepSeekProperties properties;

    /*
    *基于私有数据（es库中的strategy）构建上下文并想DeepSeek提问
    * 参数1：用户发出的问题
    * 参数2：私有库的攻略数组
    * */
    public String askWithStrategies(String question, List<Strategy> strategies){
        //用于构建字符串的对象，使用'\n\n'确保私库的数据片段（json格式）有清晰的分隔
        StringJoiner joiner = new StringJoiner("\n\n");
        //给AI立人设，做定位。还可以指定输出的长度
        joiner.add("你是一个资深导游。请基于提供的私有旅行攻略片段结合question关键字对应的互联网数据进行整理并作出回答。如果资料不足，请明确说明不知道。\n\n" +
                "以下是来自私有库的内容片段（JSON）： ");
        //遍历查询到的私库数据片段，每个strategy就是一个片段
        for (Strategy strategy : strategies) {
            //把得到的java格式的私有数据片段转换成json格式
            String json = JSON.toJSONString(strategy);
            //把json格式的私有片段添加到joiner中
            joiner.add(json);
        }
        //结合私库片段的请求数据
        String systemPrompt = joiner.toString();

        //整合发送给大模型的消息。消息分很多角色，其中system表示系统角色，用于设置背景、行为、角色等信息。我们设置了
        //当前ai是导游，并将私有数据也添加到这里，相当于导游拥有私有库的知识片段。system角色用于设置大的背景，一把在
        //会话的第一次设置。user角色用于设置用户真实的问题
        List<Map<String, Object>> messages = new ArrayList<>();
        Map<String, Object> systemMessage = new HashMap<>();
        systemMessage.put("role", "system");
        systemMessage.put("content", systemPrompt);
        messages.add(systemMessage);
        Map<String, Object> userMessage = new HashMap<>();
        userMessage.put("role", "user");
        userMessage.put("content", question);
        messages.add(userMessage);

        //构建请求对象
        Map<String, Object> openAiChatRequest = new HashMap<>();
        //设置模型名称为deepseek-chat, 用于和deepseek交流的模型
        openAiChatRequest.put("model", properties.getModel());
        //发送给大模型的消息
        openAiChatRequest.put("messages", messages);
        //直译是温度，这里表示回答的随机性
        openAiChatRequest.put("temperature", 1.3);

        //http请求头
        HttpHeaders httpHeaders = new HttpHeaders();
        //请求的数据格式为json
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        //设置授权认证，填写的是deepseek的api密钥
        httpHeaders.setBearerAuth(properties.getApiKey());

        //用请求头和请求对象构建请求实体
        HttpEntity<Map<String, Object>> httpEntity = new HttpEntity<>(openAiChatRequest, httpHeaders);

        //请求的地址
        String url = properties.getBaseUrl();

        url = url+"/chat/completions";

        //java中的http请求客户端，用来发送http请求
        RestTemplate restTemplate = new RestTemplate();
        /*
        * 调用http的post方式发送请求
        * 参数1： 请求地址
        * 参数2： 请求实体
        * 参数3： 返回数据的类型
        * 返回值： deepseek大模型应答的数据
        * */
        Map map = restTemplate.postForObject(url, httpEntity, Map.class);

        System.err.println("应答结果：");
        System.err.println(map);
        System.err.println("========");

        //无结果判断
        if(map == null || map.get("choices") == null){
            return "(无回答)";
        }
        List choices = (List) map.get("choices");
        if(choices.isEmpty()){
            return "(无回答)";
        }

        //拿到返回数据，解析出ai应答的内容并返回
        Map choice = (Map) choices.get(0);
        Map message = (Map) choice.get("message");
        String content = (String) message.get("content");

        return content;
    }


}
